package com.metersbonwe.basetest.core;

import org.junit.runners.model.InitializationError;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.metersbonwe.basetest.annotation.TestDisplay;
import com.metersbonwe.basetest.annotation.TestProfile;
import com.metersbonwe.basetest.annotation.TestTask;
import com.metersbonwe.basetest.proxy.Proxys;
import com.metersbonwe.basetest.proxy.TestTaskMethodInterceptor;

public class TonyJUnit4ClassRunner extends /* BlockJUnit4ClassRunner */SpringJUnit4ClassRunner {

	public TonyJUnit4ClassRunner(Class<?> clazz) throws InitializationError {
		super(clazz);
	}

	@Override
	protected Object createTest() throws Exception {
		TestProfile tp = getTestClass().getJavaClass().getAnnotation(TestProfile.class);

		final Object _o = super.createTest();
		if (tp == null)
			return _o;

		if (_o instanceof Task) {
			return createProxyBean(tp, new ProxyObject() {
				public Object createProxy() {
					try {
						return TonyJUnit4ClassRunner.super.createTest();
					} catch (Exception e) {
						e.printStackTrace();
					}
					return _o;
				}
			});
		} else if (Proxys.containsAnnotation(_o, TestTask.class)) {
			return createProxyBean(tp, new ProxyObject() {
				public Object createProxy() {
					try {
						return new TaskProxy(TonyJUnit4ClassRunner.super.createTest());
					} catch (Exception e) {
						e.printStackTrace();
					}
					return _o;
				}
			});
		}
		return _o;
	}

	private Object createProxyBean(TestProfile tp, ProxyObject proxyCreater) throws InstantiationException,
			IllegalAccessException, Exception {
		setDisplay();
		int threadCount = tp.threadCount();
		int whileCount = tp.whileCount();
		TestClient testClient = new TestClient(threadCount, whileCount);
		for (int i = 0; i < threadCount; i++) {
			testClient.addTaskClass(proxyCreater.createProxy());
		}
		TestTaskMethodInterceptor interceptor = new TestTaskMethodInterceptor(testClient);
		Object proxyobj = Proxys.getProxyInstance(getTestClass().getJavaClass(), interceptor);
		return proxyobj;
	}

	private void setDisplay() {
		TestDisplay display = getTestClass().getJavaClass().getAnnotation(TestDisplay.class);
		if (display != null) {
			Task.lvl1 = display.lvl1();
			Task.lvl2 = display.lvl2();
			Task.lvl3 = display.lvl3();
			Task.lvl4 = display.lvl4();
			Task.lvl5 = display.lvl5();
		}
	}

}
